namespace ui {

	let $fillColor: number = Color.Default.FILL;	//(当前绘图)填充颜色(默认灰)
	let $lineColor: number = Color.Default.LINE;	//(当前绘图)线条颜色(默认绿)
	let $fillAlpha: number = 1;						//(当前绘图)填充透明度
	let $lineAlpha: number = 1;						//(当前绘图)线条透明度
	let $thickness: number = 1;						//(当前绘图)线条粗细
	let $dashArray: number[] = [10, 10];			//(当前绘图)虚线样式
	let $p1: [number, number];
	let $p2: [number, number];

	function _upCreate(shape: egret.Shape): egret.Shape {
		if (!!shape && shape instanceof egret.Shape) return shape;
		else return new egret.Shape();
	}

	function _resetLine(options: hjc.DrawOptions, shape?: egret.Shape): egret.Shape {
		let line = _upCreate(shape);
		line.graphics.lineStyle(Math.notNegtive(options.thickness) ? options.thickness : $thickness,
			isColor(options.lineColor) ? options.lineColor : $lineColor,
			numeric(options.lineAlpha) ? options.lineAlpha : $lineAlpha,
			undefined, undefined, undefined, undefined, undefined, !!options.lineDash ? $dashArray : undefined);
		return line;
	}

	function _resetFill(options: hjc.DrawOptions, shape?: egret.Shape): egret.Shape {
		let filled = _upCreate(shape);
		filled.graphics.beginFill(isColor(options.fillColor) ? options.fillColor : $fillColor,
			numeric(options.fillAlpha) ? options.fillAlpha : $fillAlpha);
		return shape;
	}

	function _drawLines(shape: egret.Shape, ...xys: number[][]): egret.Shape {
		xys.forEach((xy: number[], i: number) => i <= 0 ? shape.graphics.moveTo(xy[0], xy[1]) : shape.graphics.lineTo(xy[0], xy[1]));
		return shape;
	}

	function _validP(options: hjc.DrawOptions, warn?: string): boolean {
		if (!!options.p && options.p instanceof egret.Point) { $p1 = [options.p.x, options.p.y]; return true; }
		if (notEmptyArr(options.xy) && options.xy.length >= 2) { $p1 = [options.xy[0], options.xy[1]]; return true; }
		if (numeric(options.x) && numeric(options.y)) { $p1 = [options.x, options.y]; return true; }
		if (!!warn) hjc.require(warn, 'Point', 'p', 'xy', 'x&y'); return false;
	}

	function _validP2(options: hjc.DrawOptions, warn?: string): boolean {
		if (!!options.p2 && options.p2 instanceof egret.Point) { $p2 = [options.p2.x, options.p2.y]; return true; }
		if (notEmptyArr(options.xy2) && options.xy2.length >= 2) { $p2 = [options.xy2[0], options.xy2[1]]; return true; }
		if (numeric(options.x2) && numeric(options.y2)) { $p2 = [options.x2, options.y2]; return true; }
		if (!!warn) hjc.require(warn, 'Point2', 'p2', 'xy2', 'x2&y2'); return false;
	}


	export function resetLineColor(lineColor: number): any { if (isColor(lineColor)) $lineColor = lineColor; else hjc.wrong('ui.resetLineColor', 'is invalid color'); return ui; }
	export function resetFillColor(fillColor: number): any { if (isColor(fillColor)) $fillColor = fillColor; else hjc.wrong('ui.resetFillColor', 'is invalid color'); return ui; }
	export function resetLineAlpha(lineAlpha: number): any { if (numeric(lineAlpha)) $lineAlpha = lineAlpha; else hjc.wrong('ui.resetLineAlpha', 'is invalid number'); return ui; }
	export function resetFillAlpha(fillAlpha: number): any { if (numeric(fillAlpha)) $fillAlpha = fillAlpha; else hjc.wrong('ui.resetFillAlpha', 'is invalid number'); return ui; }
	export function resetThickness(thickness: number): any { if (Math.notNegtive(thickness)) $thickness = thickness; else hjc.wrong('ui.resetThinkness', 'is invalid non-negtive number'); return ui; }
	export function resetGraphics(): any { $fillColor = Color.Default.FILL; $lineColor = Color.Default.LINE; $fillAlpha = $lineAlpha = $thickness = 1; $dashArray = [10, 10]; return ui; }

	export function drawLine(options: hjc.DrawOptions, line?: egret.Shape): egret.Shape {
		if (!!line) line.graphics.clear();
		let _line = _resetLine(options, line);
		//多点式(ps)
		if (notEmptyArr(options.ps) && options.ps.length >= 2) return _drawLines(_line, ...options.ps.map(p => [p.x, p.y]));
		//多点式(xys)
		if (notEmptyArr(options.xys) && options.xys.length >= 2) return _drawLines(_line, ...options.xys);
		//点角线式(p|xy|x&y + angle + length)
		if (_validP(options) && numeric(options.angle) && numeric(options.length)) return _drawLines(_line, $p1, [$p1[0] +
			Math.sin(Math.angleToRadian(options.angle)) * options.length, $p1[1] + Math.cos(Math.angleToRadian(options.angle)) * options.length]);
		//两点式(p|xy|x&y + p2|xy2|x2&y2)
		if (_validP(options) && _validP2(options)) return _drawLines(_line, $p1, $p2);
		hjc.require('ui.drawline', 'points(xys) or point-slope', 'ps[]', 'xys[]', 'p|xy|x&y+angle+length', 'p|xy|x&y+p2|xy2|x2&y2'); return line;
	}

	export function drawGrids(options: hjc.DrawOptions, grids?: egret.Shape): egret.Shape {
		let [colNum, rowNum, gw, gh] = [0, 0, 0, 0];
		if (Math.isPositive(options.gridSize)) { gw = options.gridSize; gh = options.gridSize; }
		if (Math.isPositive(options.gridWidth)) gw = options.gridWidth;
		if (Math.isPositive(options.gridHeight)) gh = options.gridHeight;
		if (!Math.isPositive(gw) || !Math.isPositive(gh)) { hjc.require('ui.drawGrids', 'positive number', 'gridSize', 'gridWidth&Height'); return grids; }
		if (!Math.isPosInt(options.colNum) || !Math.isPosInt(options.rowNum)) { hjc.require('ui.drawGrids', 'positive interger', 'colNum', 'rowNum'); return grids; }
		else { colNum = options.colNum; rowNum = options.rowNum; }
		if (!!grids) grids.graphics.clear();
		let _grids = _resetLine(options, grids);
		let [w, h] = [colNum * gw, rowNum * gh];
		for (let row = 0; row <= rowNum; row++) { _drawLines(_grids, [0, row * gh], [w, row * gh]); }
		for (let col = 0; col <= colNum; col++) { _drawLines(_grids, [col * gw, 0], [col * gw, h]); }
		return _grids;
	}

	export function drawArc(options: hjc.DrawOptions, arc?: egret.Shape): egret.Shape {
		let [aS, aE, r] = [0, 0, 0];
		if (!Math.notNegtive(options.radius)) { hjc.require('ui.drawArc', 'non-negtive number', 'radius'); return arc; }
		else r = options.radius;
		if (numeric(options.angleStart)) aS = Math.angleToRadian(options.angleStart);
		if (numeric(options.angle) || numeric(options.angleEnd)) aE = numeric(options.angleEnd) ?
			Math.angleToRadian(options.angleEnd) : Math.angleToRadian(options.angleStart + options.angle);
		else { hjc.require('ui.drawArc', 'number', 'angle|angleEnd'); return arc; }
		if (!!arc) arc.graphics.clear();
		let _arc = _resetLine(options, arc);
		if (options.centered === false) _arc.graphics.drawArc(-r, -r, r, aS, aE, options.clockwise === false);
		else _arc.graphics.drawArc(0, 0, r, aS, aE, options.clockwise === false);
		return _arc;
	}

	export function drawRect(options: hjc.DrawOptions, rect?: egret.Shape): egret.Shape {
		let [w, h] = [null, null];
		let [x, y] = [options.x, options.y];
		if (!x) { x = 0 }
		if (!y) { y = 0 }
		if (Math.isPositive(options.size)) { w = options.size; h = options.size; }
		if (Math.isPositive(options.width)) w = options.width;
		if (Math.isPositive(options.height)) h = options.height;
		if (!w || !h) { hjc.require('ui.drawRect', 'positive number', 'size', 'width&height'); return rect; }
		if (!!rect) rect.graphics.clear();
		let _rect = _resetFill(options, _resetLine(options, rect));
		if (!!options.centered) _rect.graphics.drawRect(-w / 2 + x, -h / 2 + y, w, h);
		else _rect.graphics.drawRect(x, y, w, h);
		_rect.graphics.endFill(); return _rect;
	}

	export function drawCircle(options: hjc.DrawOptions, circle?: egret.Shape): egret.Shape {
		if (!Math.notNegtive(options.radius)) { hjc.require('ui.drawCircle', 'non-negtive number', 'radius'); return circle; }
		if (!!circle) circle.graphics.clear();
		let r = options.radius;
		let _circle = _resetFill(options, _resetLine(options, circle));
		if (options.centered === false) _circle.graphics.drawCircle(-r, -r, r);
		else _circle.graphics.drawCircle(0, 0, r);
		_circle.graphics.endFill(); return _circle;
	}

	export function drawCurve(options: hjc.DrawOptions, curve?: egret.Shape): egret.Shape {
		hjc.todo('ui.drawCurve'); return curve;
	}

	export function drawSector(options: hjc.DrawOptions, sector?: egret.Shape): egret.Shape {
		hjc.todo('ui.drawSector'); return sector;
	}

	export function drawArch(options: hjc.DrawOptions, arch?: egret.Shape): egret.Shape {
		hjc.todo('ui.drawArch'); return arch;
	}

	export function drawEllipse(options: hjc.DrawOptions, ellipse?: egret.Shape): egret.Shape {
		hjc.todo('ui.drawEllipse'); return ellipse;
	}

	export function drawPolygon(options: hjc.DrawOptions, polygon?: egret.Shape): egret.Shape {
		let xys = [];
		if (notEmptyArr(options.ps) && options.ps.length >= 3) options.ps.map(p => xys.push([p.x, p.y]));
		else if (notEmptyArr(options.xys) && options.xys.length >= 3) xys = options.xys;
		else { hjc.require('ui.drawPolygon', 'Points(≥3)', 'ps[]|xys[]'); return polygon; }
		if (!!polygon) polygon.graphics.clear();
		xys.push(xys.head());
		let _polygon = _resetFill(options, _resetLine(options, polygon));
		_drawLines(_polygon, ...xys);
		_polygon.graphics.endFill(); return _polygon;
	}

	export function drawRegularPolygon(options: hjc.DrawOptions, regularPloygon?: egret.Shape): egret.Shape {
		let [n, r] = [0, 0];
		if (Math.isPosInt(options.num) && options.num >= 3) n = options.num;
		else { hjc.require('ui.drawRegularPolygon', 'positive integer(≥3)', 'num'); return regularPloygon; }
		if (!Math.notNegtive(options.radius)) { hjc.require('ui.drawRegularPolygon', 'non-negtive number', 'radius'); return regularPloygon; }
		else r = options.radius;
		if (!!regularPloygon) regularPloygon.graphics.clear();
		let _rp = _resetFill(options, _resetLine(options, regularPloygon));
		let [angle, xys] = [2 * Math.PI / n, []];
		for (let i = 0; i < n; i++) { xys.push([r * Math.cos(angle * i), r * Math.sin(angle * i)]); }
		xys.push(xys.head());
		if (options.centered === false) xys = xys.map(xy => [xy[0] + r, xy[1] + r]);
		_drawLines(_rp, ...xys);
		_rp.graphics.endFill(); return _rp;
	}

	export function drawStar(options: hjc.DrawOptions, start?: egret.Shape): egret.Shape {
		hjc.todo('ui.drawStar'); return start;
	}

	export function drawCapsule(options: hjc.DrawOptions, capsule?: egret.Shape): egret.Shape {
		hjc.todo('ui.drawCapsule'); return capsule;
	}
}

	// 	/**
	// 	 * 创建或者重置多边形
	// 	 * @param params 创建或者重置参数
	// 	 * @param convex 重置直线绘图
	// 	 * @return 创建或者重置结果
	// 	 */
	// 	export function _drawConvex(params: hjc.TDraw, convex?: egret.Shape): egret.Shape {

	// 	}
